# 标准库导入
import socket
import logging
from contextlib import asynccontextmanager, closing

# 第三方库导入
from fastapi import FastAPI, WebSocket
import uvicorn

# 应用初始化 ====================================================
def create_app() -> FastAPI:
    """Factory function for FastAPI application"""
    @asynccontextmanager
    async def lifespan(app: FastAPI):
        """生命周期管理"""
        # 启动逻辑
        logging.info(f"Connecting to Redis: {settings.redis_url}")
        await redis.ping()
        
        yield
        
        # 关闭逻辑
        await openai_client.aclose()
        await redis.aclose()

    return FastAPI(
        title="WeChat-OpenAI Bridge",
        lifespan=lifespan
    )

app = create_app()

# 调试配置 ======================================================
def setup_debugger():
    """调试器初始化"""
    try:
        import debugpy
        if not debugpy.is_client_connected():
            debugpy.listen(('0.0.0.0', 5678))
            logging.info("调试器监听端口 5678...")
            debugpy.wait_for_client()
    except Exception as e:
        logging.error(f"调试器连接失败: {str(e)}")

# 工具函数 ======================================================
def check_port(port: int) -> bool:
    """端口占用检查"""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        result = s.connect_ex(('localhost', port))
        logging.debug(f"端口 {port} 检测结果: {result}")
        return result != 0

def find_port_process(port: int) -> int | None:
    """查找占用端口的进程ID"""
    import psutil
    for conn in psutil.net_connections():
        if conn.laddr.port == port and conn.status == 'LISTEN':
            return conn.pid
    return None

# WebSocket路由 ================================================
@app.websocket("/ws/{user_id}")
async def websocket_endpoint(websocket: WebSocket, user_id: str):
    """WebSocket消息入口"""
    await chat.websocket_endpoint(websocket, user_id)

# 主程序入口 ====================================================
if __name__ == "__main__":
    # 初始化日志
    logging.basicConfig(level=logging.DEBUG)
    
    # 端口检查
    for port in [5678, 8000]:
        if not check_port(port):
            if (pid := find_port_process(port)) is not None:
                logging.warning(f"端口 {port} 被进程 {pid} 占用，终止命令: taskkill /F /PID {pid}")
            raise SystemExit(f"端口 {port} 已被占用")

    # 启动调试器
    setup_debugger()
    
    # 启动服务
    uvicorn.run(
        "app.main:app",
        host="0.0.0.0",
        port=8000,
        reload=True,
        use_colors=False
    )